﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;

namespace library
{
    [JsonObject(MemberSerialization.OptIn)]
    public class p2pPost
    {
        bool binary = true;

        [JsonProperty("A")]
        public string Base64Address
        {
            get { return Utils.ToBase64String(address); }
            set { address = Utils.FromBase64String(value); }
        }


        [JsonProperty("B")]
        public string TargetBase64Address
        {
            get { return Utils.ToBase64String(targetAddress); }
            set { targetAddress = Utils.FromBase64String(value); }
        }

        internal byte[] targetAddress;

        internal byte[] Data
        {
            get { return content; }
        }

        public byte[] Address
        {
            get { return address; }
            set { address = value; }
        }

        byte[] address;

        byte[] content;

        byte[] hash;

        [JsonProperty("C")]
        public string Content
        {
            get
            {
                return binary ? null : HttpUtility.HtmlEncode(Encoding.Unicode.GetString(content));
            }
            set
            {
                binary = false;

                content = Encoding.Unicode.GetBytes(value);
            }
        }

        public static p2pPost Create(
            p2pPost post,
            byte[] address = null,
            byte[] targetAddress = null)
        {
            return Create(
                Utils.ToBase64String(post.Address),
                address,
                targetAddress);
        }

        public static p2pPost Create(
            string content,
            byte[] address = null,
            byte[] targetAddress = null)
        {
            var post = Create(Encoding.Unicode.GetBytes(content), address, targetAddress);

            post.binary = false;

            LocalIndex.ParseContent(post.Address, content);

            return post;
        }

        public static p2pPost Create(
            byte[] content,
            byte[] address = null,
            byte[] targetAddress = null)
        {
            p2pPost post = new p2pPost(address, targetAddress);

            post.content = content;

            post.hash = Utils.ComputeHash(content, 0, content.Length);

            LocalPosts.Add(post);

            return post;
        }
        
        public p2pPost(
            byte[] address = null,
            byte[] targetAddress = null)
        {
            Address = address ?? Utils.GetAddress();

            this.targetAddress = targetAddress;

        }

        public  byte[] ToBytes()
        {
            return new byte[] { (byte)PacketTypes.Post }.
                Concat(BitConverter.GetBytes(content.Length)).
                Concat(content).
                Concat(targetAddress ?? new byte[0]).
                Concat(BitConverter.GetBytes(binary)).
                ToArray();
        }

        public static p2pPost FromBytes(byte[] address, byte[] packet)
        {
            if (packet.Length < 1)
                return null;

            var offset = 0;

            if (packet[offset++] != (byte) PacketTypes.Post)
                return null;

            var content = Utils.ReadBytes(packet, offset);
                        
            offset += content.Length;

            var targetAddress = Utils.ReadBytes(packet, offset);

            p2pPost result = null; //new p2pPost(value, address, targetAddress);

            //todo:remover
            //result.TextValue = Encoding.Unicode.GetString(value);

            return result;
        }

        //var terms = value.Split(' ');

        //    foreach (var term in terms)
        //        LocalIndex.AddAddress(Encoding.Unicode.GetBytes(term), result.Address);
        
        public bool Equals(p2pPost value)
        {
           return Addresses.Equals(this.Address, value.Address);
        }

    }
}
